/*
//   Copyright 2008 Dear Soft(http://dear-soft.com)
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
 */

package com.dear.soft.components.properties;

import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;

import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableModel;

import com.dear.soft.components.properties.Category.CategoryExpander;
import com.dear.soft.components.properties.renderers.ExpanderCellRenderer;
import com.dear.soft.components.properties.renderers.NameCellRenderer;
import com.dear.soft.components.properties.renderers.ReferenceExpander;
import com.dear.soft.components.properties.renderers.ReferenceName;
import com.dear.soft.components.properties.renderers.ReferenceValue;
import com.dear.soft.components.properties.renderers.ValueCellRenderer;

public class PropertiesTable extends JTable {
	private static final long serialVersionUID = 1L;
	private boolean flatMode = false;

	public PropertiesTable() {
		super(new PropertiesTableModel());
		setDefaultRenderer(ReferenceExpander.class, new ExpanderCellRenderer());
		setDefaultRenderer(ReferenceName.class, new NameCellRenderer());
		setDefaultRenderer(ReferenceValue.class, new ValueCellRenderer());
		defineColumns();

		addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				if (e.getClickCount() > 0) {
					int column = columnAtPoint(new Point(e.getX(), e.getY()));
					if (column == 0) {
						int row = rowAtPoint(new Point(e.getX(), e.getY()));
						tryToExpandCollapse(row);
					}
				}
			}

		});
	}

	protected void tryToExpandCollapse(int row) {
		PropertiesTableModel model = (PropertiesTableModel) getModel();
		Object value = model.getValueAt(row, 0);
		if (value instanceof CategoryExpander) {
			CategoryExpander expander = (CategoryExpander) value;
			expander.ref.swapFolding();
			tableChanged(null);
			this.repaint();
		}
	}

	public void collapse() {
		PropertiesTableModel model = (PropertiesTableModel) getModel();
		for (Category c : model.getCategories()) {
			c.collapse();
		}
		tableChanged(null);
	}

	public void expand() {
		PropertiesTableModel model = (PropertiesTableModel) getModel();
		for (Category c : model.getCategories()) {
			c.expand();
		}
		tableChanged(null);
	}

	public void setFlatMode(boolean mode) {
		if (this.flatMode != mode) {
			this.flatMode = mode;
			PropertiesTableModel model = (PropertiesTableModel) getModel();
			model.setFlatMode(flatMode);
		}
	}

	public void tableChanged(TableModelEvent e) {
		super.tableChanged(e);
		defineColumns();
	}

	private void defineColumns() {
		JTableHeader header = getTableHeader();
		if (header != null) {
			setTableHeader(null);
		}
		getColumnModel().getColumn(0).setResizable(false);
		getColumnModel().getColumn(1).setResizable(true);
		getColumnModel().getColumn(2).setResizable(true);
		getColumnModel().getColumn(0).setWidth(12);
		getColumnModel().getColumn(0).setPreferredWidth(12);
		getColumnModel().getColumn(0).setMaxWidth(12);
		setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
	}

	@Override
	public void setModel(TableModel model) {
		if (!(model instanceof PropertiesTableModel)) {
			throw new RuntimeException(
					"This class expect PropertiesTableModel only");
		}
		PropertiesTableModel current = (PropertiesTableModel) getModel();
		PropertiesTableModel properties = (PropertiesTableModel) model;
		if (current != null) {
			int index = 0;
			List<Category> newCategories = properties.getCategories();
			for (Category c : current.getCategories()) {
				if (newCategories.size() < (index + 1)) {
					break;
				}
				if (c.isExpanded()) {
					newCategories.get(index).expand();
				}
				index++;
			}

		}

		super.setModel(properties);
		properties.setFlatMode(flatMode);
		properties.addTableModelListener(this);
		defineColumns();
	}

}
